package com.vf.admin.common;

import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vf.admin.client.common.ClientConstants;
import com.vf.admin.client.common.RedisKeys;
import com.vf.admin.client.dao.*;
import com.vf.admin.client.service.*;
import com.vf.admin.client.tx.utils.TxIm;
import com.vf.admin.client.tx.vo.RoomGiftVo;
import com.vf.admin.client.tx.vo.UserShiZhi;
import com.vf.admin.client.tx.vo.userSignVo;
import com.vf.admin.common.entity.Result;
import com.vf.admin.common.entity.ResultVo;
import com.vf.admin.common.redis.RedisUtil;
import com.vf.admin.miaodong.entity.*;
import com.vf.admin.utils.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Query;

import static com.vf.admin.client.tx.utils.TxIm.getOnlineMemberNum;
import static com.vf.admin.utils.StringEx.isNull;

/**
 * 定时器
 */
@Component
@Slf4j
public class Scheduler {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Resource
    RedisUtil redisUtil;
    @Resource
    AppRoomService appRoomService;
    @Resource
    AppUserService appUserService;
    @Resource
    AppGiftService appGiftService;
    @Resource
    AppGiftNumService appGiftNumService;
    @Resource
    AppSetupService appSetupService;
    @Resource
    AppUserDressupDao appUserDressupDao;
    @Resource
    AppUserDressupService appUserDressupService;
    @Autowired
    private AppInvitationRecordService appInvitationRecordService;
    @Autowired
    private AppGuardService appGuardService;
    @Autowired
    private MessageChatFromService messageChatFromService;
    @Autowired
    private LovelyGodLogService lovelyGodLogService;

    //缓存信息的时间(分钟)
    private final Integer TIME = 120;

    /**
     * @return
     * @throws MalformedObjectNameException 获取当前tomcat机器的端口号
     */
    public String getLocalPort() throws MalformedObjectNameException {
        MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
        Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"),
                Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
        String port = objectNames.iterator().next().getKeyProperty("port");
        return port;
    }


    /**
     * 定时更新房间在线人数
     * 执行时间：10秒
     */
    @Scheduled(fixedRate = 10 * 1000)
    public void dingshiroomzaixian() {
//        try {
//            //端口号验证
//            /*  if (getLocalPort().equals(Constants.CHUSHIHUA_DUANKOU)) {*/
//            //获取全部房间
//            List<AppRoom> room = appRoomService.getRoomFiveMinute();
//            //遍历
//            for (AppRoom appRoom : room) {
//                //根据房间的腾讯code，调用腾讯方接口，获取在线人数
//                int zaixian = getOnlineMemberNum(appRoom.getTengxuncode());
//                //存入redis
//                redisUtil.hset("RoomOnline", "" + appRoom.getTengxuncode(), zaixian + "");
//                //当在线人数为0时，修改房间直播状态
//                if (zaixian == 0) {
//                    //变更房间直播状态  不直播
//                    appRoomService.updateRoomZhiboState(appRoom.getId(), 2);
//                }
//            }
//            /*}*/
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 定时清理断线的用户
     * 执行时间：60秒
     */
    @Scheduled(fixedRate = 60 * 1000)
    public void dingshiuserDuanxian() {
        try {
            //端口号验证
            //  if (getLocalPort().equals(Constants.CHUSHIHUA_DUANKOU)) {
            //获取全部断线用户
            Map<String, Date> duanxin = Constants.duanxianUserMap;
            //遍历
            for (Map.Entry<String, Date> entry : duanxin.entrySet()) {
                //取key
                String mapKey = entry.getKey();
                //取value
                Date mapValue = entry.getValue();
                long date = mapValue.getTime();
                //获取当前时间
                Calendar calendar = Calendar.getInstance();
                long now = calendar.getTimeInMillis();
                //获取差值
                long delta = now - date;
                //判断差值是否大于30秒
                if (delta > 60000 * 2) {
                    AppUser user = appUserService.getTengxuncodeByUser(Integer.valueOf(mapKey));
                    //过期，修改在线状态
                    appUserService.onlineUpstate(user.getId(), 2);
                }
            }
            //}
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 定时清理视频匹配,超过30秒清除
     * 执行时间：10秒
     */
    @Scheduled(fixedRate = 5000)
    public void cleanUpVideoMatchesRegularly() {
        try {
            //获取性别男的信息
            Map<Object, Object> map1 = redisUtil.hmget("videoMatch1");
            //获取性别女的信息
            Map<Object, Object> map2 = redisUtil.hmget("videoMatch2");
            //遍历男
            for (Map.Entry<Object, Object> entry : map1.entrySet()) {
                //取key
                Object mapKey = entry.getKey();
                //取value
                Object mapValue = entry.getValue();
                //value里取出的是时间戳，因此转换为long
                long date = Long.valueOf(String.valueOf(mapValue)).longValue();
                //获取当前时间
                Calendar calendar = Calendar.getInstance();
                long now = calendar.getTimeInMillis();
                //获取差值
                long delta = now - date;
                //判断差值是否大于30秒
                if (delta > 30000) {
                    //过期，清除信息
                    redisUtil.hdel("videoMatch1", mapKey);
                }
            }
            //遍历男
            for (Map.Entry<Object, Object> entry : map2.entrySet()) {
                //取key
                Object mapKey = entry.getKey();
                //取value
                Object mapValue = entry.getValue();
                //value里取出的是时间戳，因此转换为long
                long date = Long.valueOf(String.valueOf(mapValue)).longValue();
                //获取当前时间
                Calendar calendar = Calendar.getInstance();
                long now = calendar.getTimeInMillis();
                //获取差值
                long delta = now - date;
                //判断差值是否大于30秒
                if (delta > 30000) {
                    //过期，清除信息
                    redisUtil.hdel("videoMatch2", mapKey);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 开始房间送礼消息推送
     * 执行时间：2秒
     */
    @Scheduled(fixedRate = 2000)
    public void executeRoomGiftNewsPush() {
        //System.out.println("定时器执行【开始房间送礼消息推送】");
        try {
            //用于存放礼物消息
            Map<Object, Object> chuLi = new HashMap<>(16);
            //从消息中取出值
            for (Map.Entry<String, Object> entry : ClientConstants.xiaoxiCacheMap.entrySet()) {
                Object mapKey = entry.getKey();
                Object mapValue = entry.getValue();
                //放入
                chuLi.put(mapKey, mapValue);
            }
            //腾讯code 初值
            Integer roomTxCode = 0;
            //存放普通礼物消息
            List<RoomGiftVo> toList = new ArrayList<>();
            //存放全服礼物消息
            List<RoomGiftVo> toQuanfuList = new ArrayList<>();
            //遍历存放礼物消息map
            for (Map.Entry<Object, Object> entry : chuLi.entrySet()) {
                //取key
                Object mapKey = entry.getKey();
                //取value
                Object mapValue = entry.getValue();
                //mapValue转json
                JSONObject jsonObject = JSON.parseObject(mapValue.toString());
                //收礼人用户id
                Integer userid = jsonObject.getInteger("userid");
                //送礼人腾讯code
                Integer sluserid = jsonObject.getInteger("sluserid");
                //房间id
                Integer roomid = jsonObject.getInteger("roomid");
                //收礼人增加的魅力值数量
                Integer meilizhis = jsonObject.getInteger("meilizhis");
                //送的礼物id
                Integer giftid = jsonObject.getInteger("giftid");
                //礼物数量id
                Integer giftNumid = jsonObject.getInteger("giftNumid");
                //根据用户id获取收礼人信息
                AppUser user = appUserService.get(userid);
                //根据腾讯code获取送礼人信息
                AppUser sluser = appUserService.getTengxuncodeByUser(sluserid);
                //根据房间id获取房间信息
                AppRoom room = appRoomService.getById(roomid);
                //根据礼物id获取礼物信息
                AppGift gift = appGiftService.get(giftid);
                //根据礼物数量id获取礼物数量
                AppGiftNum giftNum = appGiftNumService.get(giftNumid);
                //腾讯code
                roomTxCode = room.getTengxuncode();
                //保存消息体
                RoomGiftVo vo = new RoomGiftVo();
                vo.setCharmNum(meilizhis);
                vo.setShouliUser(sluser.getTengxuncode());
                vo.setShouliUserNiCheng(sluser.getNick());
                vo.setSongliUser(user.getTengxuncode());
                vo.setSongliUserNiCheng(user.getNick());
                vo.setSongliUserPic(user.getPic());
                //获取用户头饰
                String toushi = "";
                AppUserDressup userDressup = appUserDressupDao.getUserid(sluser.getId(), 2);
                if (!org.springframework.util.StringUtils.isEmpty(userDressup)) {
                    toushi = userDressup.getGoodpic();
                }
                Integer headHalo = 0;
                Integer isVip = 0;
                //获取用户腾讯方最新的数据
                String re = TxIm.portraitGget(sluser.getTengxuncode());
                if (!isNull(re)) {
                    JSONObject jsonObject1 = JSON.parseObject(re);
                    headHalo = jsonObject1.getInteger("headHalo");
                    isVip = jsonObject1.getInteger("isVip");
                }
                vo.setHeadHalo(headHalo);
                vo.setHeadWear(toushi);
                vo.setGiftName(gift.getGiftname());
                vo.setGiftNum(giftNum.getNum());
                vo.setGifteffects(gift.getGifteffects());
                vo.setGiftTexiao(gift.getSvgaaddress());
                vo.setXiaoxi(user.getNick() + "赠送给" + sluser.getNick() + gift.getGiftname() + "  X" + giftNum.getNum());
                toList.add(vo);
                //如果是全服礼物，存入全服消息list
                if (gift.getShifouquanfu() == 1) {
                    toQuanfuList.add(vo);
                }
                //调用腾讯方接口,更新用户信息
                userSignVo vo1 = new userSignVo();
                vo1.setId(sluser.getId());
                vo1.setCharmNum(meilizhis);
                vo1.setHeadWear(toushi);
                vo1.setHeadHalo(headHalo);
                vo1.setNobleid(sluser.getNobleid());
                vo1.setStatus(sluser.getStatus());
                vo1.setIsVip(isVip);
                net.sf.json.JSONObject obj1 = net.sf.json.JSONObject.fromObject(vo1);
                UserShiZhi shiZhi = new UserShiZhi();
                shiZhi.setUserSign(obj1.toString());
                shiZhi.setTengxuncode(sluser.getTengxuncode() + "");
                TxIm.portraitSet(shiZhi);
                //删除map的值
                ClientConstants.xiaoxiCacheMap.remove(mapKey.toString());
            }

            if (toList.size() > 0 && roomTxCode != 0) {
                //发送房间魅力值增加消息
                String json = JSONArray.fromObject(toList).toString();
                ResultVo result = new ResultVo();
                result.setCode(20);
                result.setMessageType(20);
                result.setData(json);
                net.sf.json.JSONObject obj = net.sf.json.JSONObject.fromObject(result);
                String json1 = obj.toString().replace("\"", "\"");
                TxIm.sendGroupMsg(roomTxCode, json1);
            }
            if (toQuanfuList.size() > 0) {
                System.out.println("发送了全服礼物");
                //发送全服礼物消息
                String json = JSONArray.fromObject(toQuanfuList).toString();
                ResultVo result = new ResultVo();
                result.setCode(23);
                result.setMessageType(23);
                result.setData(json);
                net.sf.json.JSONObject obj = net.sf.json.JSONObject.fromObject(result);
                String json1 = obj.toString().replace("\"", "\"");
                AppSetup setup = appSetupService.get();
                System.out.println("官方群号：" + setup.getGftxcode());
                System.out.println("发送json：" + json1);

                TxIm.sendGroupMsg(setup.getGftxcode(), json1);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 定时清理用户会员
     */
    @Scheduled(cron = "0 1 0 * * ?")
    public void vipExpired() {
        try {
            List<AppUser> userList = appUserService.vipExpired();
            if(userList != null && userList.size() > 0) {
                String userIds = userList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                appUserService.updateVipExpire(userIds);
            }

            //更新腾讯方数据
            if(userList != null && userList.size() > 0) {
                for(AppUser u : userList) {
                    String re = TxIm.portraitGget(u.getTengxuncode());
                    Integer headHalo = 0;
                    Integer charmNum = 0;
                    Integer status = 0;
                    Integer nobleid = 0;
                    String headWear = "";
                    if (!isNull(re)) {
                        JSONObject jsonObject1 = JSON.parseObject(re);
                        headHalo = jsonObject1.getInteger("headHalo");
                        charmNum = jsonObject1.getInteger("charmNum");
                        headWear = jsonObject1.getString("headWear");
                        status = jsonObject1.getInteger("status");
                        nobleid = jsonObject1.getInteger("nobleid");
                    }
                    userSignVo vo1 = new userSignVo();
                    vo1.setId(u.getId());
                    vo1.setCharmNum(charmNum);
                    vo1.setHeadWear(headWear);
                    vo1.setHeadHalo(headHalo);
                    vo1.setNobleid(nobleid);
                    vo1.setStatus(status);
                    vo1.setIsVip(0);
                    net.sf.json.JSONObject obj1 = net.sf.json.JSONObject.fromObject(vo1);
                    UserShiZhi shiZhi = new UserShiZhi();
                    shiZhi.setUserSign(obj1.toString());
                    shiZhi.setTengxuncode(u.getTengxuncode() + "");
                    TxIm.portraitSet(shiZhi);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 定时清理用户个人装扮的坐骑/头饰过期
     * 执行时间：60秒
     */
    @Scheduled(fixedRate = 3600 * 1000)
    public void dingshiuserZhuangban() {
        try {
            //端口号验证
            /*  if (getLocalPort().equals(Constants.CHUSHIHUA_DUANKOU)) {*/
            //获取全部房间
            List<AppUserDressup> userDressupList = appUserDressupService.selectNoGuoqi();
            //遍历
            for (AppUserDressup userDressup : userDressupList) {
                if(userDressup.getOvertime() != null) {
                    long date = userDressup.getOvertime().getTime();
                    //获取当前时间
                    Calendar calendar = Calendar.getInstance();
                    long now = calendar.getTimeInMillis();
                    //获取差值
                    long delta = date - now;
                    //判断差值是否大于0
                    if (delta < 0) {
                        if (userDressup.getState() == 1) {
                            AppUser user = appUserService.get(userDressup.getUserid());
                            //获取用户腾讯方最新的数据
                            String re = TxIm.portraitGget(user.getTengxuncode());
                            Integer headHalo = 0;
                            Integer charmNum = 0;
                            Integer isVip = 0;
                            if (!isNull(re)) {
                                JSONObject jsonObject1 = JSON.parseObject(re);
                                headHalo = jsonObject1.getInteger("headHalo");
                                charmNum = jsonObject1.getInteger("charmNum");
                                isVip = jsonObject1.getInteger("isVip");
                            }
                            //重新设置资料
                            userSignVo vo1 = new userSignVo();
                            vo1.setId(user.getId());
                            vo1.setCharmNum(charmNum);
                            vo1.setHeadWear("");
                            vo1.setHeadHalo(headHalo);
                            vo1.setNobleid(user.getNobleid());
                            vo1.setStatus(user.getStatus());
                            vo1.setIsVip(isVip);
                            net.sf.json.JSONObject obj1 = net.sf.json.JSONObject.fromObject(vo1);
                            UserShiZhi shiZhi = new UserShiZhi();
                            shiZhi.setUserSign(obj1.toString());
                            shiZhi.setTengxuncode(user.getTengxuncode() + "");
                            TxIm.portraitSet(shiZhi);
                        }
                        //过期，修改时间
                        appUserDressupService.del(userDressup.getId());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 定时填充账号池
     * 执行时间：60秒
     */
    @Scheduled(fixedRate = 600 * 1000)
    public void fillingUserCode() {
        try {
            //端口号验证
            /*  if (getLocalPort().equals(Constants.CHUSHIHUA_DUANKOU)) {*/
            long size = redisUtil.lGetListSize("chi:usercode");
            if (size < 500) {
                do {
                    long qushi = 500 - size;
                    if(qushi > 50) qushi = 50;
                    String userCodeArr = "";
                    for (int i = 0; i < qushi; i++) {
                        String usercode = RandomUtil.eightUserID();
                        userCodeArr += "," + usercode;
                    }
                    if (!isNull(userCodeArr)) {
                        userCodeArr = userCodeArr.substring(1);
                    }
                    List<AppUser> userList = appUserService.getPiliang(userCodeArr);
                    for (AppUser user : userList) {
                        boolean status = userCodeArr.contains(user.getUsercode() + "");
                        if (status) {
                            String yuan = "," + user.getUsercode();
                            userCodeArr = userCodeArr.replace(yuan, "");
                        }
                    }
                    String[] arr = userCodeArr.split(",");
                    for (String s : arr) {
                        redisUtil.lSet("chi:usercode", s, TIME * 60);
                    }
                    size += arr.length;
                } while (size < 500);
            }
            /*}*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 定时填充用户腾讯code池
     * 执行时间：60秒
     */
    @Scheduled(fixedRate = 600 * 1000)
    public void fillingTxCode() {
        try {
            //端口号验证
            /*  if (getLocalPort().equals(Constants.CHUSHIHUA_DUANKOU)) {*/
            long size = redisUtil.lGetListSize("chi:txcode");
            if (size < 500) {
                do {
                    long qushi = 500 - size;
                    if(qushi > 50) qushi = 50;
                    String txCodeArr = "";
                    for (int i = 0; i < qushi; i++) {
                        String txcode = RandomUtil.eightUserID9();
                        txCodeArr += "," + txcode;
                    }
                    if (!isNull(txCodeArr)) {
                        txCodeArr = txCodeArr.substring(1);
                    }
                    List<AppUser> userList = appUserService.getPiliangTengxuncodeByUser(txCodeArr);
                    for (AppUser user : userList) {
                        boolean status = txCodeArr.contains(user.getUsercode() + "");
                        if (status) {
                            String yuan = "," + user.getTengxuncode();
                            txCodeArr = txCodeArr.replace(yuan, "");
                        }
                    }
                    String[] arr = txCodeArr.split(",");
                    for (String s : arr) {
                        redisUtil.lSet("chi:txcode", s, TIME * 60);
                    }
                    size += arr.length;
                } while (size < 500);
            }

            /*}*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 定时填充用户邀请码池
     * 执行时间：60秒
     */
    @Scheduled(fixedRate = 600 * 1000)
    public void fillingYaoqingma() {
        try {
            //端口号验证
            /*  if (getLocalPort().equals(Constants.CHUSHIHUA_DUANKOU)) {*/
            long size = redisUtil.lGetListSize("chi:yaoqingma");
            if (size < 500) {
                do {
                    long qushi = 500 - size;
                    if(qushi > 50) qushi = 50;
                    String yaoqingmaArr = "";
                    String sqlArr = "";
                    for (int i = 0; i < qushi; i++) {
                        String yaoqingma = RandomUtil.getInstance().generateXxString(6);
                        yaoqingmaArr += "," + yaoqingma + "";
                        sqlArr += ",'" + yaoqingma + "'";
                    }
                    if (!isNull(yaoqingmaArr)) {
                        yaoqingmaArr = yaoqingmaArr.substring(1);
                        sqlArr = sqlArr.substring(1);
                    }
                    List<AppUser> userList = appUserService.getPiliangYaoqingma(sqlArr);
                    for (AppUser user : userList) {
                        boolean status = yaoqingmaArr.contains(user.getCode() + "");
                        if (status) {
                            String yuan = "," + user.getCode() + "";
                            yaoqingmaArr = yaoqingmaArr.replace(yuan, "");
                        }
                    }
                    String[] arr = yaoqingmaArr.split(",");
                    for (String s : arr) {
                        redisUtil.lSet("chi:yaoqingma", s, TIME * 60);
                    }
                    size += arr.length;
                } while (size < 500);
            }
            /*}*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 定时填充房间code池
     * 执行时间：60秒
     */
    @Scheduled(fixedRate = 600 * 1000)
    public void fillingRoomCode() {
        try {
            //端口号验证
            /*  if (getLocalPort().equals(Constants.CHUSHIHUA_DUANKOU)) {*/
            long size = redisUtil.lGetListSize("chi:roomcode");
            if (size < 500) {
                do {
                    long qushi = 500 - size;
                    String roomCodeArr = "";
                    for (int i = 0; i < qushi; i++) {
                        String roomcode = RandomUtil.eightUserID();
                        roomCodeArr += "," + roomcode;
                    }
                    if (!isNull(roomCodeArr)) {
                        roomCodeArr = roomCodeArr.substring(1);
                    }
                    List<AppRoom> roomList = appRoomService.getPiliang(roomCodeArr);
                    for (AppRoom room : roomList) {
                        boolean status = roomCodeArr.contains(room.getRoomcode() + "");
                        if (status) {
                            String yuan = "," + room.getRoomcode();
                            roomCodeArr = roomCodeArr.replace(yuan, "");
                        }
                    }
                    String[] arr = roomCodeArr.split(",");
                    for (String s : arr) {
                        redisUtil.lSet("chi:roomcode", s, 60 * 60);
                    }
                    size+=arr.length;
                } while (size < 500);
            }

            /*}*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 根据存储的邀请记录发放邀请奖励
     */
    @Scheduled(fixedRate = 600 * 1000)
    @Transactional
    public void trackInviteSent(){
        AppSetup setup = appSetupService.get();
        List<AppInvitationRecord> appInvitationRecords = appInvitationRecordService.trackInviteSent(1);
        appInvitationRecords.forEach(e->{
            AppUser user = appUserService.lockGet(e.getPuserid());
            appUserService.addDiamonds(user.getId(), new BigDecimal(String.valueOf(setup.getSubordinatereward())), "邀请用户奖励");
            e.setStatus(2);
            e.setSupermoney(Double.valueOf(setup.getSubordinatereward()));
            appInvitationRecordService.save(e);
        });
    }


    /**
     * 执行检查亲密度降低，每天晚上23:50执行一次
     */
    @Scheduled(cron = "0 50 23 * * ?")
    public void decIntimacy() {
        appGuardService.decIntimacy();
    }

}
